﻿using System;
using System.IO;
using System.Reflection;

namespace Cpuss.ReportGenerator
{

    /// <summary>
    /// CPUSS Console Report Generation Tool.
    /// </summary>
    class Program
    {

        /// <summary>
        /// Invokes a simulation taking into account the user provided flags.
        /// </summary>
        /// <param name="args">Flags to use for the simulation.</param>
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Usage();
                Environment.Exit(1);
            }
            try
            {
                FlagParser parser = new FlagParser(args);
                parser.Parse();
                object[] arguments = new object[parser.ConstructorArguments.Count];
                for (int i = 0; i < arguments.Length; i++)
                {
                    arguments[i] = parser.ConstructorArguments[i];
                }

                StrategyFactory factory = new StrategyFactory(parser.Strategy, arguments);
                IStrategy strategy = factory.CreateInstance();
                if (strategy == null)
                {
                    Console.WriteLine("Unable to find the strategy provided.");
                    Environment.Exit(1);
                }
                DateTime before = DateTime.Now;
                HtmlReport report = new HtmlReport(new RepeatRunner(parser.Small, parser.Medium, parser.Large, strategy, parser.Repeat, parser.Window),
                    parser.Report, parser.Outdir);
                report.Create();
                DateTime after = DateTime.Now;
                Console.WriteLine("Total execution time of simulations: {0}(s)", (after - before).TotalSeconds);
            }
            catch (ArgumentException ex)
            {
                Console.WriteLine(ex.Message);
            }
            catch (UnauthorizedAccessException ex)
            {
                Console.WriteLine(ex.Message);
            }
            catch (MissingMethodException)
            {
                Console.WriteLine("The strategy specified doesn't support the provided number of arguments.");
            }
            catch (DirectoryNotFoundException ex)
            {
                Console.WriteLine(ex.Message);
            }
        }


        /// <summary>
        /// Writes usage instuctions to the console.
        /// </summary>
        private static void Usage()
        {
            Console.WriteLine("CPUSS HTML Report Generator version: {0}", Assembly.GetExecutingAssembly().GetName().Version);
            Console.WriteLine("http://codeplex.com/cpuss");
            Console.WriteLine("\nCPUSS: Usage");
            Console.WriteLine(" default file extension is \".html\"");
            Console.WriteLine("\n options:");
            Console.WriteLine("     /report[:file]\t--\tName of the report file");
            Console.WriteLine("     /strategy:<type>,arg1<int32>,arg2<int32>,...,argN<int32>\t--\tStrategy to use");
            Console.WriteLine("     /repeat:<int32>\t--\t# of times to run the simulation");
            Console.WriteLine("     /small:<int32>\t--\t# of small processes");
            Console.WriteLine("     /medium:<int32>\t--\t# of medium processes");
            Console.WriteLine("     /large:<int32>\t--\t# of large processes");
            Console.WriteLine("     /outdir:<string>\t--\tOutput directory of the report");
            Console.WriteLine("     /window:<int32>\t--\tTime window to use for throughput");
            Console.WriteLine("\nExample Usage:");
            Console.WriteLine(@"cpussrg /report:sjfe /outdir:c:\myreports /strategy:ShortestJobFirstExpert,5,33 /repeat:20 /small:12 /large:45");
            Console.WriteLine("\nTerminating...");
        }

    }

}